/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands.extension;

import org.eclipse.core.runtime.Assert;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Extension;
import org.eclipse.uml2.uml.Property;

import com.cea.papyrus.core.IPapyrusUIConstants;
import com.cea.papyrus.core.commands.association.DeleteAssociationFromModelCommand;
import com.cea.papyrus.core.helper.IGraphEdgeHelper;
import com.cea.papyrus.core.helper.IModelerHelper;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.core.utils.Debug;

/**
 * 
 * 
 * @author Remi SCHNEKENBURGER
 */
public class DeleteExtensionFromModelCommand extends DeleteAssociationFromModelCommand  {
	
	/**
	 * debug channel.
	 */
	private final static int channel = 21;
	
	/**
	 * Dependency to delete.
	 */
	private org.eclipse.uml2.uml.Extension extension;
	
	/**
	 * Owner of the dependency to delete.
	 */
	private Element parent;
	
	/**
	 * stores the source property.
	 */
	private Property sourceProperty;
	
	/**
	 * stores the source property owner.
	 */
	private Classifier sourcePropertyOwner;
	
	/**
	 * stores the target property.
	 */
	private Property targetProperty;
	
	/**
	 * stores the target property owner.
	 */
	private Classifier targetPropertyOwner;

	/**
	 * Creates a new DeleteExtensionFromModelCommand.
	 * 
	 * @param extension the extension to delete
	 */
	public DeleteExtensionFromModelCommand(Extension extension) {
		super(extension);
		Assert.isNotNull(extension);
		setLabel("Delete Extension "+extension.getName());
		this.extension = extension;
		parent = extension.getOwner();
		
		// save properties
		this.sourceProperty = (Property)extension.getMemberEnds().get(1);
		this.sourcePropertyOwner = (Classifier)sourceProperty.getOwner();
		this.targetProperty = (Property)extension.getMemberEnds().get(0);
		this.targetPropertyOwner = (Classifier)targetProperty.getOwner();
		
	}

	
    /**
     * Return the ClassDiagram modelerHelper
     * @TODO Remove this kind of references to another plugin !
     * This command should be independant from any diagram. The implementation inside this method 
     * looks like a dependance on classdiagram !
     */
    private IModelerHelper getClassDiagramModelerHelper() {
        return ModelerHelper.getFactory(IPapyrusUIConstants.CLASS_DIAGRAM);
    }
    
	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#execute()
	 */
	/**
	 * 
	 */
	@Override
	public void execute() {
		Debug.debug(this, "DeleteExtensionFromModel.execute -> "+extension, channel);
		Assert.isNotNull(parent, "DeleteExtension.child has no parent");
		
		// delete using connect/reconnect
		if(elementFactory instanceof IGraphEdgeHelper) {
			// deconnect extension from properties
		    getClassDiagramModelerHelper().deconnect(Extension.class, sourceProperty, targetProperty, extension);
			
			// remove properties
		    getClassDiagramModelerHelper().removeElement(Property.class, targetProperty, targetPropertyOwner);
		    getClassDiagramModelerHelper().removeElement(Property.class, sourceProperty, sourcePropertyOwner);
			
			// remove extension
		    getClassDiagramModelerHelper().removeElement(Extension.class, extension, parent);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#redo()
	 */
	/**
	 * 
	 */
	@Override
	public void redo() {
		execute();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#undo()
	 */
	/**
	 * 
	 */
	@Override
	public void undo() {
		Debug.debug(this, "DeleteExtensionFromModel.execute -> "+extension, channel);
		Assert.isNotNull(parent, "DeleteExtension.child has no parent");
		
		// undo delete using connect/reconnect
		if(elementFactory instanceof IGraphEdgeHelper) {
			// recreate extension
		    getClassDiagramModelerHelper().addUMLElement(Extension.class, extension, parent);
			
			// recreate properties (warning: add second first)
		    getClassDiagramModelerHelper().addUMLElement(Property.class, sourceProperty, sourcePropertyOwner);
		    getClassDiagramModelerHelper().addUMLElement(Property.class, targetProperty, targetPropertyOwner);
			
			// connect extension and properties
		    getClassDiagramModelerHelper().connect(Extension.class, sourceProperty, targetProperty, extension);
			
		}

	}
	
	
//	/** debug channel */
//	private final static int channel = 21;
//	
//	/** PrimitiveType to delete */
//	private org.eclipse.uml2.uml.Extension child;
//	
//	/** Owner of the package to delete */
//	private Element parent;
//	
//	/** Save source and target element */
//	private List<Property> memberEnds = new ArrayList<Property>();
//	
//	/** 
//	 * Default Constructor
//	 */
//	public DeleteExtensionFromModelCommand(Extension child) {
//		if (child == null) {
//			throw new IllegalArgumentException();
//		}
//		setLabel("Delete <Extension>"+child.getName());
//		this.child = child;
//		this.parent = child.getOwner();
//	}
//	
//	/* (non-Javadoc)
//	 * @see org.eclipse.gef.commands.Command#execute()
//	 */
//	@Override
//	public void execute() {
//		Debug.debug(this, "DeleteExtensionFromModel.execute -> "+child, channel);
//		Assert.isNotNull(parent, "DeleteExtension.child has no parent");
//		if(parent instanceof Package) {
//			// save member ends
//			child.eAdapters().clear();
//			memberEnds = child.getMemberEnds();
//			Iterator<Property> it = memberEnds.iterator();
//			while(it.hasNext()) {
//				Property property = it.next();
//				property.setExtension(null);
//				property.eAdapters().clear();
//			}
//			Debug.debug(this, "DeleteExtensionFromModel.execute -> "+child, channel);
//			((Package)parent).getPackagedElements().remove(child);
//		} else {
//			throw new RuntimeException("Extension.delete is not in a package");
//		}
//		
//	}
//
//	/* (non-Javadoc)
//	 * @see org.eclipse.gef.commands.Command#redo()
//	 */
//	@Override
//	public void redo() {
//		execute();
//	}
//
//	/* (non-Javadoc)
//	 * @see org.eclipse.gef.commands.Command#undo()
//	 */
//	@Override
//	public void undo() {
//		if(parent instanceof Package) {
//			((Package)parent).getPackagedElements().add(child);
//			Iterator<Property> it = memberEnds.iterator();
//			while(it.hasNext()) {
//				Property property = it.next();
//				Debug.debug(this, "adding extension "+child.getName()+" to "+property.getName(), channel);
//				property.setExtension(child);
//			}
//		}
//	}
}
